<!--
 * @Author: WuFeng <763467339@qq.com>
 * @Date: 2022-04-25 21:18:06
 * @LastEditTime: 2023-05-17 20:39:04
 * @LastEditors: WuFeng <763467339@qq.com>
 * @Description:
 * @FilePath: \vue3-element-plus-web\src\views\SysManage\SysDict\index.vue
 * Copyright 版权声明
-->
<template>
    <standard-page
      ref="crudPage"
      v-model:page="page"
      v-model:listData="listData"
      v-model:btnLoading="btnLoading"
      v-model:listLoading="listLoading"
      :options="options"
      @on-load-data="onLoadData"
      @search-change="searchChange"
      @search-reset="resetChange"
      @refresh-change="refreshChange"
      @row-save="rowSave"
      @row-update="rowUpdate"
      @row-del="rowDel"
      @selection-change="selectionChange"
    >
    <!-- 自定义操作按钮 -->
    <template #handleBtns>
    </template>
    <!-- 状态 列卡槽 -->
    <template #column_status="scope">
      <template v-for="(item, index) in ENABLED_STATE_ENUM" :key="index">
        <template v-if="scope.row.status === item.value">
          <el-tag :type="item.type">{{item.label}}</el-tag>
        </template>
      </template>
    </template>
    <!-- 表格操作列 - 自定义操作按钮 -->
    <template #handleColumnBtns="scope">
      <el-link
        type="primary"
        title="新建子字典"
        @click="handleCreate(scope.row)"
      >
        新建子字典
      </el-link>
    </template>
  </standard-page>
</template>

<script>
import { getList, deleteSave } from '@/api/SysManage/sysDict'
import { mapGetters } from 'vuex'
// 标准增删改查页面 - 组件
import StandardPage from '@/components/StandardPage/index.vue'
import { ENABLED_STATE_ENUM } from '@/config'

// 当前模块名称
const MODULE_VALUE = 'SYS_DICT_MANAGE'

// 定义个map变量用来存储加载过的父节点信息
const lazyLoadMaps = new Map()

const load = (tree, treeNode, resolve) => {
  getList({
    current: 1,
    size: 9999,
    parentId: tree.id
  }).then(response => {
    // 将获取到的节点数据添加到 lazyLoadMaps 变量中
    lazyLoadMaps.set(tree.id, { tree, treeNode, resolve })
    const listData = response.data.records || []
    resolve(listData)
  }).catch(err => {
    err
  })
}

export default {
  name: 'SysDict',
  computed: {
    ...mapGetters([
      'drawerVisible'
    ])
  },
  components: {
    StandardPage
  },
  data() {
    return {
      // 按钮 loading 状态
      btnLoading: false,
      // 列表 loading 状态
      listLoading: false,
      // 分页信息
      page: {
        pageNum: 1,
        total: 110,
        pageSize: 10
      },
      // 查询条件
      listQuery: {},
      // 数据
      listData: [],
      options: {
        MODULE_VALUE,
        createDrawerWidth: '50%', // 新建 抽屉弹窗宽度
        updateDrawerWidth: '50%', // 编辑 抽屉弹窗宽度
        detailDrawerWidth: '30%', // 详情 抽屉弹窗宽度
        // 页面title, showHeader 为 true 时生效， 默认值： 页面标题
        title: 'CURD示例页面',
        // 结果展示区标题
        // resultTitle: '列表',
        // 是否展示 header， 默认值： true
        showHeader: true,
        // 是否展示 查询条件区域, 默认值 ： true
        showSearch: true,
        // 搜索条件标题的宽度, 默认值： 110px
        searchLabelWidth: '110px',
        // 搜索的文字， 默认值： 查询
        searchBtnText: '查询',
        // 清空的文字， 默认值： 重置
        emptyBtnText: '重置',
        // 是否展示 查询条件区域 - 【展开/折叠】 按钮， 默认值： true
        searchShowMoreBtn: false,
        // 是否展示 分页， 默认值： true
        showPage: true,
        // 是否显示表格 行多选， 默认值： false
        selection: false,
        // 是否显示表格 索引/序号 列， 默认值： false
        index: false,
        // 设置表格的序号的标题,默认为： 序号
        indexLabel: '序号',
        // 表格操作列 - 宽度
        handleColumnWidth: '240',
        // 表格操作列 - 隐藏查看按钮
        showDetailBtn: false,
        // table 属性
        tableAttr: {
          rowKey: 'id', // 行数据的 Key，用来优化 Table 的渲染； 在使用reserve-selection功能与显示树形数据时，该属性是必填的。 类型为 String 时，支持多层访问：user.info.id，但不支持 user.info[0].id，此种情况请使用 Function。
          lazy: true, // 是否懒加载子节点数据
          // 加载子节点数据的函数，lazy 为 true 时生效，函数第二个参数包含了节点的层级信息
          load(tree, treeNode, resolve) {
            load(tree, treeNode, resolve)
          },
          // 渲染嵌套数据的配置选项
          treeProps: {
            children: 'children',
            hasChildren: 'hasChildren'
          }
        },
        // 字段配置
        column: [
          {
            show: false, // 在列表中不展示此列， 一般用于在列表不展示，在查询条件中展示
            label: '关键字', //
            prop: 'key',
            search: true, // 是否在搜索区作为查询条件展示， 默认值： false
            searchType: 'text', // 定义搜索框的类型， 默认值： text ， 枚举： text 、 select 、 selectMultiple 、 checkbox 、 radio 、 daterange 、 datetime
            searchPlaceholder: '请输入字典码、字典值、字典名称', // 输入框占位文本
            searchTip: '请输入关键字', // 辅助提示语
            searchTipPlacement: 'left' // 提示语的方向
          },
          {
            label: '字典名称',
            prop: 'dictValue',
            width: 200, // 对应列的最小宽度， 对应列的最小宽度， 与 width 的区别是 width 是固定的，min-width 会把剩余宽度按比例分配给设置了 min-width 的列
            align: 'left' // 水平对称方式， 默认： left ， 枚举：left、center、right
            //search: true, // 是否在搜索区作为查询条件展示， 默认值： false
            //searchType: 'text', // 定义搜索框的类型， 默认值： text ， 枚举： text 、 select 、 selectMultiple 、 checkbox 、 radio 、 daterange 、 datetime
            //searchPlaceholder: '请输入字典名称', // 输入框占位文本
            //searchTip: '字典名称', // 辅助提示语
            //searchTipPlacement: 'left' // 提示语的方向
          },
          {
            label: '字典值',
            prop: 'dictKey',
            width: 120, // 对应列的最小宽度， 对应列的最小宽度， 与 width 的区别是 width 是固定的，min-width 会把剩余宽度按比例分配给设置了 min-width 的列
            align: 'center' // 水平对称方式， 默认： left ， 枚举：left、center、right
            //search: true, // 是否在搜索区作为查询条件展示， 默认值： false
            //searchType: 'text', // 定义搜索框的类型， 默认值： text ， 枚举： text 、 select 、 selectMultiple 、 checkbox 、 radio 、 daterange 、 datetime
            //searchPlaceholder: '请输入字典值', // 输入框占位文本
            //searchTip: '字典值', // 辅助提示语
            //searchTipPlacement: 'left' // 提示语的方向
          },
          {
            label: '字典码',
            prop: 'code',
            width: 140, // 对应列的最小宽度， 对应列的最小宽度， 与 width 的区别是 width 是固定的，min-width 会把剩余宽度按比例分配给设置了 min-width 的列
            align: 'left' // 水平对称方式， 默认： left ， 枚举：left、center、right
            // search: true // 是否在搜索区作为查询条件展示， 默认值： false
            //searchType: 'text', // 定义搜索框的类型， 默认值： text ， 枚举： text 、 select 、 selectMultiple 、 checkbox 、 radio 、 daterange 、 datetime
            //searchPlaceholder: '请输入字典码', // 输入框占位文本
            //searchTip: '字典码', // 辅助提示语
            //searchTipPlacement: 'left' // 提示语的方向
          },
          {
            label: '字典备注',
            prop: 'remark',
            minWidth: 140, // 对应列的最小宽度， 对应列的最小宽度， 与 width 的区别是 width 是固定的，min-width 会把剩余宽度按比例分配给设置了 min-width 的列
            align: 'left' // 水平对称方式， 默认： left ， 枚举：left、center、right
            //search: true, // 是否在搜索区作为查询条件展示， 默认值： false
            //searchType: 'text', // 定义搜索框的类型， 默认值： text ， 枚举： text 、 select 、 selectMultiple 、 checkbox 、 radio 、 daterange 、 datetime
            //searchPlaceholder: '请输入字典备注', // 输入框占位文本
            //searchTip: '字典备注', // 辅助提示语
            //searchTipPlacement: 'left' // 提示语的方向
          },
          {
            label: '状态',
            prop: 'status',
            width: 80,
            align: 'center',
            search: true, // 是否在搜索区作为查询条件展示
            searchType: 'select', // 定义搜索框的类型， 默认值： text ， 枚举： text 、 select 、 selectMultiple 、 checkbox 、 radio 、 daterange 、 datetime
            dictData: ENABLED_STATE_ENUM // searchType / formType 如果为 checked 、 radio 、 select 等需要枚举的配置此值
          },
          {
            label: '排序',
            prop: 'sort',
            width: 80, // 对应列的最小宽度， 对应列的最小宽度， 与 width 的区别是 width 是固定的，min-width 会把剩余宽度按比例分配给设置了 min-width 的列
            align: 'center' // 水平对称方式， 默认： left ， 枚举：left、center、right
            //search: true, // 是否在搜索区作为查询条件展示， 默认值： false
            //searchType: 'text', // 定义搜索框的类型， 默认值： text ， 枚举： text 、 select 、 selectMultiple 、 checkbox 、 radio 、 daterange 、 datetime
            //searchPlaceholder: '请输入排序', // 输入框占位文本
            //searchTip: '排序', // 辅助提示语
            //searchTipPlacement: 'left' // 提示语的方向
          }
        ]
      },
      // 状态 枚举
      ENABLED_STATE_ENUM
    }
  },
  watch: {
  },
  created() {
  },
  activated() {
  },
  deactivated() {
  },
  methods: {
    // 新建子部门
    handleCreate(row) {
      this.$store.dispatch('ShowDrawer', {
        module: MODULE_VALUE,
        type: 'CREATE',
        size: '40%',
        params: {
          pageParams: {
            parentId: row.id,
            parentName: row.dictValue,
            parentCode: row.code,
            rowBAK: row
          }
        }
      }).then(res => {

      })
    },
    // 加载数据
    onLoadData(params) {
      /**
       * SetReloadPage 传递过来的参数
        this.$store.dispatch('SetReloadPage', {
          // 是否需要重载， true ： 需要 ， false ： 不需要
          reload: true,
          // 重载时传递参数
          reloadParams: data
        })
       */
      const reloadParams = params.reloadParams || {
        params: {}
      }
      const type = reloadParams.type
      let parentId = reloadParams.params.parentId || 0
      if (type === 'CREATE') {
        parentId = reloadParams.params.id || 0
      }

      if (parentId !== 0) {
        let grandpaId = 0
        // 新建时先刷新爷爷级
        if (type === 'CREATE') {
          grandpaId = reloadParams.params.parentId
          if (grandpaId === 0) {
            this.getList(params, grandpaId)
          } else {
            // 根据更改节点的父ID取出响应数据
            const { tree, treeNode, resolve } = lazyLoadMaps.get(grandpaId)
            if (tree) {
              // 将取出对应数据再传给load方法
              load(tree, treeNode, resolve)
            }
          }
        }
        // 根据更改节点的父ID取出响应数据
        const { tree, treeNode, resolve } = lazyLoadMaps.get(parentId)
        const crudPage = this.$refs.crudPage.getTableRef()
        crudPage.store.states.lazyTreeNodeMap.value[parentId] = []
        if (tree) {
          // 将取出对应数据再传给load方法
          load(tree, treeNode, resolve)
          return
        }
      }
      this.getList(params, parentId)
    },
    // 加载数据
    getList(params, parentId) {
      if (typeof params !== 'undefined') {
        this.listQuery = Object.assign({}, this.listQuery, params.query)
      }

      // 查询条件处理
      const queryParams = JSON.parse(JSON.stringify(this.listQuery))
      if (typeof queryParams.dateRange !== 'undefined') {
        if ((queryParams.dateRange).length > 0) {
          queryParams.startTime = queryParams.dateRange[0]
          queryParams.endTime = queryParams.dateRange[1]
          delete queryParams.dateRange
        } else {
          queryParams.startTime = ''
          queryParams.endTime = ''
          delete queryParams.dateRange
        }
      }
      queryParams.parentId = parentId

      this.btnLoading = true
      this.listLoading = true
      return getList({
        current: this.page.pageNum,
        size: this.page.pageSize,
        ...queryParams
      }).then(response => {
        // this.listData = response.data.lstItem || []
        // this.page.total = response.data.page.total || 0

        this.listData = response.data.records || []
        this.page.total = response.data.total || 0

        this.btnLoading = false
        this.listLoading = false
      }).catch(err => {
        err
        this.btnLoading = false
        this.listLoading = false
      })
    },
    // 点击搜索后执行方法
    searchChange(params) {
      console.log('点击搜索按钮回调', params)
    },
    // 点击清空的执行方法
    resetChange(params) {
      console.log('清空回调', params)
    },
    // 刷新数据
    refreshChange(params) {
      console.log('刷新数据', params)
    },
    // 新增数据
    rowSave(params) {
      console.log('新增数据', params)
    },
    // 修改数据
    rowUpdate(params) {
      console.log('修改数据', params)
    },
    // 删除数据
    rowDel(params) {
      // console.log('删除数据', params)
      deleteSave({
        ids: params.data.id
      }).then(response => {
        this.$notify({
          title: '提示',
          message: '删除成功',
          type: 'success',
          duration: 2000
        })
        const parentId = params.data.parentId
        // 重载table树某节点数据
        this.onLoadData({
          reloadParams: {
            type: 'DELETE',
            params: {
              parentId
            }
          }
        })
      }).catch(err => {
        err
      })
    },
    // selectionChange
    selectionChange(data) {
      console.log('selectionChange:', data)
    }
  }
}
</script>

<style rel="stylesheet/scss" lang="scss" scoped>
</style>
